#include "stm32f10x.h"
#include "bsp_usart.h"
#include "menu.h"
#include "FreeRTOS.h"
#include "task.h"
#include "AD.h"
#include "DHT11.h"
#include "Store.h"
#include "timers.h"
#include "onenet.h"
#include "TimerTick.h"
#include "semphr.h"
#include "application.h"
extern Auto_Value a;
u16 AD0,AD1;
double data[4] = {0,0,0,0};
int control = 0,sendFlag = 1,controlFlag = 1;//0000 0001 0001 0001 Pump256 Fan16 Led1
TaskHandle_t AppTaskCreate_Handle;
TaskHandle_t task_handle1 = NULL;
TaskHandle_t task_handle2 = NULL;
TaskHandle_t task_handle3 = NULL;
TaskHandle_t task_handle4 = NULL;
TimerHandle_t xTimeHandle1 = NULL;

SemaphoreHandle_t ControlMu_Handle = NULL;
void Get_Store(void);
void Ad_Task (void* parameter);//读取传感器任务 7
void One_Task(void* parameter);//OneNet Push任务 9
void Two_Task(void* parameter);//OneNet 接收任务 8
void Control_Task(void* parameter);//控制电机任务 6
static void AppTaskCreate(void* parameter)
{
    taskENTER_CRITICAL();           //进入临界区
    xTaskCreate(Ad_Task,"Ad_Task",256,NULL,7,&task_handle1);
    xTaskCreate(One_Task,"OnePost_Task",256,NULL,9,&task_handle2);
    xTaskCreate(Two_Task,"OneGet_Task",128,NULL,8,&task_handle3);
    xTaskCreate(Control_Task,"Control_Task",150,NULL,6,&task_handle4);
    Menu_Task_Create();//prio-5
    vTaskDelete(AppTaskCreate_Handle); //删除AppTaskCreate任务
    taskEXIT_CRITICAL();            //退出临界区
}

int main()
{
    //USART_Config();
    Motor_Init();//水泵不能和串口1共用
    delay_init();
    Menu_Init();
    AD_Init();
    Store_Init();
    Get_Store();
    BaseType_t xReturn = pdPASS;
    xReturn = xTaskCreate((TaskFunction_t)AppTaskCreate,"AppTaskCreate",128,NULL,3,&AppTaskCreate_Handle);
//    if (pdPASS==xReturn)
//    {
//        printf("/******System is Successfully loaded!******/\n");
//    }

    vTaskStartScheduler();
    while(1);
}
void Ad_Task (void* parameter) {
    u8 flag1 = 0,flag2 = 0,flag3 = 0;//多个异常标志，以防一个被覆盖
    int pcontrol = 0;
    while(1) {
        DHT_Get_DHT11_Data(&data[0],&data[1]);
        AD0 = AD_GetValue(ADC_Channel_0);
        AD1 = AD_GetValue(ADC_Channel_1);
        data[2] = (4095-AD0)/40.96+50;//土壤湿度
        data[3] = (4095-AD1)/40.96;//光照强度
        pcontrol = control;
        if(controlFlag == 1) {
            if(data[3] < a.Linten) {//Led
                control |=0x0001;
                flag1 = 1;
            }else if(data[3] > a.Linten && data[3] < a.Hinten){
                control &=0xFFF0;
                flag1 = 0;
            } else if(data[3] > a.Hinten) {
                control |=0x0004;//表示亮度过高，置位暂无操作
                flag1 = 1;
            }
            
            if(data[0] > a.Htemp) {//Fan
                control |=0x0010;
                flag2 = 1;
            }else if(data[0] > a.Ltemp && data[0] < a.Htemp){
                control &=0xFF0F;
                flag2 = 0;
            } else if(data[0] < a.Ltemp) {
                control |=0x0040;
                flag2 = 1;
            }
            
            if(data[2] < a.Lohumi) {//Pump
                control |=0x0100;
                flag3 = 1;
            }else if (data[2] > a.Lohumi && data[2] < a.Hohumi){
                control &=0xF0FF;
                flag3 = 0;
            } else if(data[2] > a.Hohumi) {
                control |=0x0400;
                flag3= 1;
            }
            
            if(pcontrol != control) {//状态改变
                if(flag1 ==1 ||flag2==1 || flag3==1) TIM_SetCompare3(TIM1,5000);
                else TIM_SetCompare3(TIM1,0);
                
                xTaskNotifyGive(task_handle4);
                flag1 = flag2 = flag3 = 0;//重置
            }
        }
        vTaskDelay(pdMS_TO_TICKS(200));
    }
}
void One_Task(void* parameter) {
    OneNet_Init();
    int count = 0;
    while(1) {
        if(count > 2) { //9s检测一次
            OneNet_Ping();
            count = 0;
        }
        OneNet_SendData(sendFlag);
        ESP8266_Clear();
        if(sendFlag != 1) {
            sendFlag = 1;
        }
        count ++;
        vTaskDelay(pdMS_TO_TICKS(3000));
    }
}
void Two_Task(void* parameter) {
    unsigned char *dataPtr = NULL;
    vTaskDelay(pdMS_TO_TICKS(3000));//等待连接到ONENET
    OneNet_Subscribe();
    while(1) {
        dataPtr = ESP8266_GetIPD(0);
        if(dataPtr != NULL)
            OneNet_RevPro(dataPtr);
        vTaskDelay(pdMS_TO_TICKS(200));
    }
}
void Control_Task(void* parameter) {
    BaseType_t r = pdFALSE;
    while(1) {
        r = ulTaskNotifyTake(pdTRUE, portMAX_DELAY);//等待任务通知
        int x = control&0x0001;
        int y = control&0x0010;
        int z = control&0x0100;
        if(z == 0x0000) {//Pump
            TIM_SetCompare1(TIM1,0);
        } else if(z== 0x0100) {
            TIM_SetCompare1(TIM1,a.Pump * 7200 / 100);
        }
        if(y == 0x0000) {//Fan 对应通道一
            TIM_SetCompare4(TIM1,0);
        } else if(y == 0x0010) {
            TIM_SetCompare4(TIM1,a.Fan * 7200 / 100);
        }
        if(x == 0x0000) {//Led
            TIM_SetCompare2(TIM1,0);
        } else if(x == 0x0001) {
            TIM_SetCompare2(TIM1,a.Led * 7200 / 100);
        }
        vTaskDelay(10);
    }
}
void Get_Store(){
    a.Htemp = Store_Data[1];//第一位为标志位
    a.Ltemp = Store_Data[2];
    a.Hohumi = Store_Data[3];
    a.Lohumi = Store_Data[4];
    a.Hinten = Store_Data[5];
    a.Linten = Store_Data[6];
}